//
// Created by ChenJi on 2022/1/6.
//
#include "GeneralUserController.h"

#define BEEP_ON HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define BEEP_OFF HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
uint16_t BeepTime = 0;

void HC_SetBeep(uint16_t time) {
    BeepTime = time;
    BEEP_ON;
}

void HC_1ms_Task_For_Beep() {
    if (BeepTime != 0) {
        BeepTime--;
        return;
    }
    BEEP_OFF;
}

void HC_General_User_Controller_Init() {
    button_init();
    registerButton(0, 500, 1, 1, 100);
}


struct ButtonHandler button0;

void onPA6Event(GPIO_PinState state) {
    if (state == GPIO_PIN_SET) {
        button0.button_latest_state = GPIO_PIN_RESET;
    } else {
        button0.button_latest_state = GPIO_PIN_SET;
    }
}


void HC_1ms_Task_For_Button() {
    handleButtons();
}

void button_init() {
    button0.buttonid = 0;
    initButton(&button0);
}

void handleButtons() {
    handleButtonTick(&button0);
}

void initButton(struct ButtonHandler *handle) {
    (*handle).button_isPressed = GPIO_PIN_RESET;
    (*handle).button_latest_state = GPIO_PIN_RESET;
    (*handle).button_listen_enable = 0;
    (*handle).button_cycle_listen = 0;
    (*handle).button_hold_callback_reg = 0;
    (*handle).button_in_long_press_mode = 0;
    (*handle).button_hold_callback_enable = 0;
    (*handle).button_reg = 0;
}

void handleButtonTick(struct ButtonHandler *handle) {
    if ((*handle).button_listen_enable == 0) return;
    if ((*handle).button_isPressed != (*handle).button_latest_state) {
        if ((*handle).button_latest_state == GPIO_PIN_SET) {
            (*handle).button_isPressed = GPIO_PIN_SET;
            (*handle).button_start_mode = 1;
            (*handle).button_reg = 0;
            onPressDownCallback(handle);               //handle on press down
        } else {
            (*handle).button_isPressed = GPIO_PIN_RESET;
            (*handle).button_reg = 0;
            (*handle).button_hold_callback_reg = 0;
            (*handle).button_in_long_press_mode = 0;
            (*handle).button_start_mode = 0;
            onFreeCallback(handle);                     //handle on free.
            if (!(*handle).button_cycle_listen) {
                (*handle).button_listen_enable = 0;
                return;
            }
        }
    }
    if ((*handle).button_long_press_mode == 0 || (*handle).button_isPressed == GPIO_PIN_RESET) {
        return;
    }
    if ((*handle).button_start_mode) {
        (*handle).button_reg++;
        if ((*handle).button_time_limit <= (*handle).button_reg) {
            (*handle).button_in_long_press_mode = 1;
            (*handle).button_reg = 0;
            (*handle).button_start_mode = 0;
            onTimeReachCallback(handle);
        }
    }
    if ((*handle).button_hold_callback_enable && (*handle).button_in_long_press_mode) {
        (*handle).button_hold_callback_reg++;
        if ((*handle).button_hold_callback_reg == (*handle).button_hold_callback_cycle) {
            (*handle).button_hold_callback_reg = 0;
            onHoldCycleCallback(handle);
        }
    }

}


void onPressDownCallback(struct ButtonHandler *handle) {
    switch ((*handle).buttonid) {
        case 0:
            onButton0PressDown();
            break;
    }
}

void onFreeCallback(struct ButtonHandler *handle) {
    switch ((*handle).buttonid) {
        case 0:
            onButton0Free();
            break;
    }
}

void onTimeReachCallback(struct ButtonHandler *handle) {
    switch ((*handle).buttonid) {
        case 0:
            onButton0TimeReach();
            break;
    }
}

void onHoldCycleCallback(struct ButtonHandler *handle) {
    switch ((*handle).buttonid) {
        case 0:
            onButton0HoldCycle();
            break;
    }
}

/**
 * register a button
 * @param buttonid button id
 * @param time long press time
 * @param mode is long press mode
 * @param cyclelisten is cycle listen
 * @param hold_callback hold on callback?
 */
void registerButton(uint8_t buttonid, uint16_t time, uint8_t mode, uint8_t cyclelisten, uint8_t hold_callback) {
    struct ButtonHandler *handle;
    switch (buttonid) {
        case 0:
            handle = &button0;
            break;
        default:
            return;

    }
    (*handle).button_listen_enable = 1;
    (*handle).button_time_limit = time;
    (*handle).button_long_press_mode = mode;
    (*handle).button_cycle_listen = cyclelisten;
    if (hold_callback != 0) {
        (*handle).button_hold_callback_enable = 1;
        (*handle).button_hold_callback_cycle = hold_callback;
    } else {
        (*handle).button_hold_callback_enable = 0;
    }
}

__weak void onButton0PressDown(){

}
__weak void onButton0Free(){

}
__weak void onButton0TimeReach(){

}
__weak void onButton0HoldCycle(){

}